<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>openlayers 加载百度地图</title>
  <link href="./libs/openlayers/v6.5.0/ol.css" rel="stylesheet">
  <script src="./libs/openlayers/v6.5.0/ol.js"></script>
  <script src="./libs/projzh/index.min.js"></script>
  <style type="text/css">
    html,
    body,
    #mainMap {
      border: 0px;
      margin: 0px;
      padding: 0px;
      width: 100%;
      height: 100%;
      font-size: 13px;
    }
  </style>
</head>

<body>
  <div id="mainMap"></div>

  <script>
    var zoom = 15;
    var maxZoom = 20;

    var bd09Extent = [-20037726.37, -12474104.17, 20037726.37, 12474104.17];
    var baiduMercator = new ol.proj.Projection({
      code: "baidu",
      extent: bd09Extent,
      units: "m"
    });
    ol.proj.addProjection(baiduMercator);
    ol.proj.addCoordinateTransforms("EPSG:4326", baiduMercator, projzh.ll2bmerc, projzh.bmerc2ll);
    ol.proj.addCoordinateTransforms("EPSG:3857", baiduMercator, projzh.smerc2bmerc, projzh.bmerc2smerc);

    var bmercResolutions = [];
    for (var i = 0; i <= 20; ++i) {
      bmercResolutions[i] = Math.pow(2, 18 - i);
    }

    var urls = [0, 1, 2, 3].map(function (sub) {
      return (
        "http://maponline" +
        sub +
        ".bdimg.com/tile/?qt=vtile&x={x}&y={y}&z={z}&styles=pl&scaler=1&udt=20191119"
      );
    });

    var source = new ol.source.XYZ({
      projection: "baidu",
      maxZoom: maxZoom,
      tileUrlFunction: function (tileCoord) {
        var x = tileCoord[1];
        var y = -tileCoord[2] - 1;
        var z = tileCoord[0];
        var hash = (x << z) + y;
        var index = hash % urls.length;
        index = index < 0 ? index + urls.length : index;
        if (x < 0) {
          x = "M" + -x;
        }
        if (y < 0) {
          y = "M" + -y;
        }
        
        return 'http://maponline' + index + '.bdimg.com/tile/?qt='+ (z === 20 ? 'v' : '') +'tile&x=' + x + '&y=' + y + '&z=' + z + '&styles=pl&scaler=1&udt=20201022&from=jsapi3_0';
      },
      tileGrid: new ol.tilegrid.TileGrid({
        resolutions: bmercResolutions,
        origin: [0, 0],
        maxZoom: maxZoom
      })
    });

    var baidu = new ol.layer.Tile({
      source: source
    });
    
    var map = new ol.Map({
      target: "mainMap",
      layers: [baidu],
      view: new ol.View({
        center: ol.proj.transform([104.06, 30.67], "EPSG:4326", "baidu"),
        projection: "baidu",
        zoom: zoom,
        extent: bd09Extent,
        maxZoom: maxZoom,
        resolutions: source.getTileGrid().getResolutions(),
        constrainResolution: true, // 是否保持整数级别缩放
      })
    });
    // let center = ol.proj.transform([104.06113602891337, 30.499892361422397], "EPSG:4326", "baidu")
    // console.log(center);
    // console.log(ol.proj.transform(center, 'baidu', 'EPSG:4326'));

    // 监听缩放
    map.getView().on("change:resolution", function (evt) {
      zoom = map.getView().getZoom();
    });

    map.on('click', (event) => {
      console.log(event.coordinate);
      console.log(ol.proj.transform(event.coordinate, 'baidu', 'EPSG:4326'))

      // 创建矢量容器
      var vectorSource = new ol.source.Vector({});
      // 创建图标特性
      var iconFeature = new ol.Feature({
          geometry: new ol.geom.Point(event.coordinate, 'XY'),
          name: '',
      });
      // 将图标特性添加进矢量中
      vectorSource.addFeature(iconFeature);

      // 创建图标样式
      var iconStyle = new ol.style.Style({
          image: new ol.style.Icon({
              opacity: 1,
              src: 'http://webmap0.bdimg.com/image/api/marker_red.png',
          }),
      });

      // 创建矢量层
      var vectorLayer = new ol.layer.Vector({
          source: vectorSource,
          style: iconStyle,
          zIndex: 1
      });
      // 添加进map层
      map.addLayer(vectorLayer);
    });
  </script>
</body>

</html>